package com.shenganyuan.smac.checkin;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Point;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.CameraPosition;
import com.amap.api.maps2d.model.Circle;
import com.amap.api.maps2d.model.CircleOptions;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.oklib.utils.calculate.ArithUtil;
import com.oklib.utils.helper.RxUtil;
import com.oklib.utils.network.http.ViseHttp;
import com.oklib.utils.network.http.callback.ACallback;
import com.oklib.utils.network.http.subscriber.ApiCallbackSubscriber;
import com.oklib.utils.view.SnackbarUtil;
import com.oklib.utils.view.ToastUtils;
import com.shenganyuan.smac.App;
import com.shenganyuan.smac.R;
import com.shenganyuan.smac.adapter.SearchResultAdapter;
import com.shenganyuan.smac.common.BaseActivity;
import com.shenganyuan.smac.common.beans.BaseBoolResult;
import com.shenganyuan.smac.common.data.Api;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 签到
 *
 * @author Damon
 */
public class ActCheckin extends BaseActivity implements AMap.OnCameraChangeListener, AMap.OnMapLoadedListener, AMapLocationListener, PoiSearch.OnPoiSearchListener, View.OnClickListener {
    private ListView listView;
    private AMap aMap;
    private MapView mapView;
    private AMapLocationClient mlocationClient;
    private AMapLocationClientOption mLocationOption;
    private Marker locationMarker, checkinMarker;
    private LatLonPoint searchLatlonPoint;
    private List<PoiItem> resultData;
    private SearchResultAdapter searchResultAdapter;
    private WifiManager mWifiManager;
    private PoiSearch poisearch;
    private Circle mcircle;
    private LatLng checkinpoint, mlocation;
    private Button locbtn;
    private TextView checkinbtn;
    private boolean isItemClickAction, isLocationAction;

    @Override
    public int getLayoutId() {
        return R.layout.act_checkin;
    }

    @Override
    public void initData() {
        super.initData();
        resultData = new ArrayList<>();
        init();
        //初始化定位
        initLocation();
        //开始定位
        startLocation();
    }

    @Override
    public void initUI(Bundle savedInstanceState) {
        mapView = findViewById(R.id.map);
        mapView.onCreate(savedInstanceState);
    }

    private void init() {
        if (aMap == null) {
            aMap = mapView.getMap();
        }
        aMap.getUiSettings().setZoomControlsEnabled(false);
        aMap.setOnCameraChangeListener(this);
        aMap.setOnMapLoadedListener(this);

        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);

        listView = findViewById(R.id.listview);
        searchResultAdapter = new SearchResultAdapter(this);
        searchResultAdapter.setData(resultData);
        listView.setAdapter(searchResultAdapter);

        listView.setOnItemClickListener(onItemClickListener);

        locbtn = findViewById(R.id.locbtn);
        locbtn.setOnClickListener(this);
        checkinbtn = findViewById(R.id.action_save);
        checkinbtn.setOnClickListener(this);
    }

    /**
     * 列表点击监听
     */
    AdapterView.OnItemClickListener onItemClickListener = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            if (position != searchResultAdapter.getSelectedPosition()) {
                PoiItem poiItem = (PoiItem) searchResultAdapter.getItem(position);
                LatLng curLatlng = new LatLng(poiItem.getLatLonPoint().getLatitude(), poiItem.getLatLonPoint().getLongitude());
                isItemClickAction = true;
                aMap.moveCamera(CameraUpdateFactory.changeLatLng(curLatlng));
                searchResultAdapter.setSelectedPosition(position);
                searchResultAdapter.notifyDataSetChanged();

            }
        }
    };

    /**
     * 初始化定位，设置回调监听
     */
    private void initLocation() {
        //初始化client
        mlocationClient = new AMapLocationClient(this.getApplicationContext());
        // 设置定位监听
        mlocationClient.setLocationListener(this);
    }

    /**
     * 设置定位参数
     *
     * @return 定位参数类
     */
    private AMapLocationClientOption getOption() {
        AMapLocationClientOption mOption = new AMapLocationClientOption();
        mOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);//可选，设置定位模式，可选的模式有高精度、仅设备、仅网络。默认为高精度模式
        mOption.setHttpTimeOut(30000);//可选，设置网络请求超时时间。默认为30秒。在仅设备模式下无效
        mOption.setNeedAddress(true);//可选，设置是否返回逆地理地址信息。默认是true
        mOption.setLocationCacheEnable(false);//设置是否返回缓存中位置，默认是true
        mOption.setOnceLocation(true);//可选，设置是否单次定位。默认是false
        return mOption;
    }

    /**
     * 开始定位
     */
    private void startLocation() {
        checkWifiSetting();
        //设置定位参数
        mlocationClient.setLocationOption(getOption());
        // 启动定位
        mlocationClient.startLocation();
    }

    /**
     * 销毁定位
     */
    private void destroyLocation() {
        if (null != mlocationClient) {
            mlocationClient.onDestroy();
            mlocationClient = null;
        }
    }

    /**
     * 地图移动过程回调
     *
     * @param cameraPosition
     */
    @Override
    public void onCameraChange(CameraPosition cameraPosition) {

    }

    /**
     * 地图移动结束回调
     * 在这里判断移动距离有无超过500米
     *
     * @param cameraPosition
     */
    @Override
    public void onCameraChangeFinish(CameraPosition cameraPosition) {
        if (!isItemClickAction && !isLocationAction) {
            searchResultAdapter.setSelectedPosition(-1);
            searchResultAdapter.notifyDataSetChanged();
        }
        if (isItemClickAction) {
            isItemClickAction = false;
        }
        if (isLocationAction) {
            isLocationAction = false;
        }

        if (mcircle != null) {
            if (mcircle.contains(cameraPosition.target)) {
                checkinpoint = cameraPosition.target;
            } else {
                ToastUtils.showToast(mContext, "微调距离不可超过500米");
                aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mlocation, 16f));
            }
        } else {
            startLocation();
            ToastUtils.showToast(mContext, "重新定位中。。。");
        }
    }

    /**
     * 地图加载完成回调
     */
    @Override
    public void onMapLoaded() {
        addMarkerInScreenCenter();
    }

    /**
     * 添加选点marker
     */
    private void addMarkerInScreenCenter() {
        LatLng latLng = aMap.getCameraPosition().target;
        Point screenPosition = aMap.getProjection().toScreenLocation(latLng);
        locationMarker = aMap.addMarker(new MarkerOptions()
                .anchor(0.5f, 0.5f)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.purple_pin)));
        //设置Marker在屏幕上,不跟随地图移动
        locationMarker.setPositionByPixels(screenPosition.x, screenPosition.y);
    }

    /**
     * 检查wifi，并提示用户开启wifi
     */
    private void checkWifiSetting() {
        if (mWifiManager.isWifiEnabled()) {
            return;
        }
        AlertDialog.Builder builder = new AlertDialog.Builder(this);  //先得到构造器
        builder.setTitle("提示"); //设置标题
        builder.setMessage("开启WIFI模块会提升定位准确性"); //设置内容
        builder.setPositiveButton("去开启", new DialogInterface.OnClickListener() { //设置确定按钮
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss(); //关闭dialog
                Intent intent = new Intent(android.provider.Settings.ACTION_WIFI_SETTINGS);
                startActivity(intent); // 打开系统设置界面
            }
        });
        builder.setNegativeButton("不了", new DialogInterface.OnClickListener() { //设置取消按钮
            @Override
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        });
        //参数都设置完成了，创建并显示出来
        builder.create().show();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mapView.onSaveInstanceState(outState);
    }

    /**
     * 方法必须重写
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
        destroyLocation();
    }


    /**
     * 返回定位结果的回调
     *
     * @param aMapLocation 定位结果
     */
    @Override
    public void onLocationChanged(AMapLocation aMapLocation) {
        if (aMapLocation != null
                && aMapLocation.getErrorCode() == 0) {
            mlocation = new LatLng(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            searchLatlonPoint = new LatLonPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude());
            checkinpoint = mlocation;
            isLocationAction = true;
            searchResultAdapter.setSelectedPosition(0);
            aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mlocation, 16f));
            if (mcircle != null) {
                mcircle.setCenter(mlocation);
            } else {
                mcircle = aMap.addCircle(new CircleOptions().strokeColor(R.color.md_green_500).center(mlocation).radius(500).strokeWidth(4));
            }
            if (searchLatlonPoint != null) {
                resultData.clear();
                resultData.add(new PoiItem("ID", searchLatlonPoint, "我的位置", searchLatlonPoint.toString()));
                doSearchQuery(searchLatlonPoint);
                searchResultAdapter.notifyDataSetChanged();
            }
        } else {
            String errText = "定位失败," + aMapLocation.getErrorCode() + ": " + aMapLocation.getErrorInfo();
            Log.e("AmapErr", errText);
            ToastUtils.showToast(mContext, errText);
        }
    }

    /**
     * 搜索周边poi
     *
     * @param centerpoint
     */
    private void doSearchQuery(LatLonPoint centerpoint) {
        PoiSearch.Query query = new PoiSearch.Query("", "", "");
        query.setPageSize(20);
        query.setPageNum(0);
        poisearch = new PoiSearch(this, query);
        poisearch.setOnPoiSearchListener(this);
        poisearch.setBound(new PoiSearch.SearchBound(centerpoint, 500, true));
        poisearch.searchPOIAsyn();
    }

    /**
     * 搜索Poi回调
     *
     * @param poiResult  搜索结果
     * @param resultCode 错误码
     */
    @Override
    public void onPoiSearched(PoiResult poiResult, int resultCode) {

        if (resultCode == AMapException.CODE_AMAP_SUCCESS) {
            if (poiResult != null && poiResult.getPois().size() > 0) {
                List<PoiItem> poiItems = poiResult.getPois();
                resultData.addAll(poiItems);
                searchResultAdapter.notifyDataSetChanged();
            } else {
                ToastUtils.showToast(mContext, "无搜索结果");
            }
        } else {
            ToastUtils.showToast(mContext, "搜索失败，错误 ");
        }
    }

    /**
     * ID搜索poi的回调
     *
     * @param poiItem    搜索结果
     * @param resultCode 错误码
     */
    @Override
    public void onPoiItemSearched(PoiItem poiItem, int resultCode) {

    }

    /**
     * Button点击事件
     *
     * @param view
     */
    @Override
    public void onClick(View view) {

        switch (view.getId()) {
            case R.id.locbtn:
                startLocation();
                break;
            case R.id.action_save:
                checkin();
                break;
            default:
                break;
        }
    }

    /**
     * 顶点签到，将签到点标注在地图上
     */
    private void checkin() {
        if (checkinMarker == null) {
            if (checkinpoint != null) {
                SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd  hh:mm:ss");
                String date = sDateFormat.format(new java.util.Date());
                checkinMarker = aMap.addMarker(new MarkerOptions().position(checkinpoint).title("签到").snippet(date));
                double longitude = checkinpoint.longitude ;
                double latitude = checkinpoint.latitude;
                longitude = ArithUtil.round(longitude, 6);
                latitude = ArithUtil.round(latitude, 6);
                requestServer(longitude + ";" + latitude);
            } else {
                startLocation();
                ToastUtils.showToast(mContext, "请定位后重试，定位中。。。");
            }
        } else {
            ToastUtils.showToast(mContext, "今日已签到");
        }
    }

    /**
     * 签到请求服务器
     *
     * @param gps
     */
    private void requestServer(String gps) {
        if (TextUtils.isEmpty(gps)) {
            SnackbarUtil.showShort(getWindow().getDecorView(), "未能获取到位置信息");
            return;
        }
        Map<String, String> req = new HashMap<>();
        req.put("djuserid", App.getCurrentUser().getId());
        req.put("gps", gps);
        req.put("token", App.getAccessToken());
        ViseHttp.RETROFIT().create(Api.class).signsave(req)
                .compose(RxUtil.rxSchedulerHelper())
                .subscribe(new ApiCallbackSubscriber<>(new ACallback<BaseBoolResult>() {
                    @Override
                    public void onSuccess(BaseBoolResult data) {
                        try {
                            if (data != null && "true".equalsIgnoreCase(data.getResult())) {
                                ToastUtils.showToast(mContext, "签到成功");
                                finish();
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            ToastUtils.showToast(mContext, "签到失败");
                        }
                    }

                    @Override
                    public void onFail(int errCode, String errMsg) {

                    }
                }));
    }
}